package com.boco.service.impl;

import com.boco.auth.BocoAuthenticationToken;
import com.boco.auth.SaltProvider;
import com.boco.auth.SimpleJpaRealm;
import com.boco.common.entity.Account;
import com.boco.domain.AccountRepository;
import com.boco.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 用户信息相关业务接口服务
 */
@Service("userService")
public class UserServiceImpl implements UserService {


    @Resource
    SaltProvider saltProvider;

    @Resource
    HashedCredentialsMatcher credentialsMatcher;

    @Resource
    SimpleJpaRealm simpleJpaRealm;

    @Resource
    AccountRepository accountRepository;


    @Override
    public Account getAccountById(String id) {
        return accountRepository.getOne(id);
    }

    @Override
    public boolean modifyAccountInfo(Account entity) {
        Account fromDb = getAccountById(entity.getId());
        entity.setPassword(fromDb.getPassword());//密码不能修改
        entity.setSalt(fromDb.getSalt());//密码不能修改
        accountRepository.save(entity);
        return true;
    }


    @Override
    public boolean modifyPassword(String oldPwd, String newPwd, String accountId) {
        Account user = accountRepository.getOne(accountId);
        checkAccount(user, oldPwd);
        String salt = saltProvider.provide();
        user.setSalt(salt);
        user.setPassword(generateCryptPwd(newPwd, salt));
        accountRepository.save(user);
        return true;
    }

    private void checkAccount(Account account, String oldPwd) {
        SecurityUtils.getSubject().login(new BocoAuthenticationToken(account.getPhone(), oldPwd, false));
    }

    @Override
    public boolean modifyAvatarUrl(String avatarUrl, String accountId) {
        Account user = accountRepository.getOne(accountId);
        user.setAvatarUrl(avatarUrl);
        accountRepository.save(user);
        return true;
    }

    @Override
    public Account registerUser(String phone, String pwd) {
        String salt = saltProvider.provide();
        List<Account> accounts = accountRepository.findAllByPhone(phone);
        Account user;
        if (accounts.size() > 0) {
            user = accounts.get(0);
        } else {
            user = new Account();
        }
        user.setPhone(phone);
        user.setPassword(generateCryptPwd(pwd, salt));
        user.setSalt(salt);
        accountRepository.save(user);
        return user;
    }

    private String generateCryptPwd(String plainText, String salt) {
        return new SimpleHash(credentialsMatcher.getHashAlgorithmName(), plainText, salt, credentialsMatcher.getHashIterations()).toBase64();
    }
}
